package com.mcj.tokendemo.util;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
import java.util.Date;
import java.util.UUID;

/**
 * JWT工具类
 */
public class JwtUtil {
	
	//有效期为
	public static final Long JWT_TTL = 60 * 60 * 1000L;		// 60 * 60 * 1000  一个小时
	//设置秘钥明文
	public static final String JWT_KEY = "mcj";
	
	public static String getUUID(){
		String token = UUID.randomUUID().toString().replaceAll("-", "");
		return token;
	}
	
	/**
	 * 生成jtw
	 * @param subject token中要存放的数据（json格式）
	 */
	public static String createJWT(String subject) {
		JwtBuilder builder = getJwtBuilder(subject, null, getUUID());	// 设置过期时间
		return builder.compact();
	}
	
	/**
	 * 生成jtw
	 * @param subject token中要存放的数据（json格式）
	 * @param ttlMillis token超时时间
	 */
	public static String createJWT(String subject, Long ttlMillis) {
		JwtBuilder builder = getJwtBuilder(subject, ttlMillis, getUUID());		// 设置过期时间
		return builder.compact();
	}
	
	private static JwtBuilder getJwtBuilder(String subject, Long ttlMillis, String uuid) {
		SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
		SecretKey secretKey = generalKey();
		long nowMillis = System.currentTimeMillis();
		Date now = new Date(nowMillis);
		if(ttlMillis==null){
			ttlMillis=JwtUtil.JWT_TTL;
		}
		long expMillis = nowMillis + ttlMillis;
		Date expDate = new Date(expMillis);
		return Jwts.builder()
				.setId(uuid)              	//唯一的ID
				.setSubject(subject)   		// 主题  可以是JSON数据
				.setIssuer("mcj")     		// 签发者
				.setIssuedAt(now)      		// 签发时间
				.signWith(signatureAlgorithm, secretKey) //使用HS256对称加密算法签名, 第二个参数为秘钥
				.setExpiration(expDate);
	}
	
	/**
	 * 创建token
	 */
	public static String createJWT(String id, String subject, Long ttlMillis) {
		JwtBuilder builder = getJwtBuilder(subject, ttlMillis, id);				// 设置过期时间
		return builder.compact();
	}
	
	public static void main(String[] args) throws Exception {
		String jwt = createJWT("000503");
		System.out.println(jwt);
		
		Claims claims = parseJWT("eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJlMjI2OTFlZTZkMmM0OWE1ODhkZjNlNzkxYTUwNzMxZCIsInN1YiI6IjEiLCJpc3MiOiJtY2oiLCJpYXQiOjE2NTE5MTE0NjksImV4cCI6MTY1MTkxNTA2OX0.PWF0ZI4PMx2_k8BK4gDiBWnQAt1CgjxMn7yB6gripa4");
		System.out.println(claims.getSubject());
		System.out.println(claims.getAudience());
		System.out.println(claims.getId());
		System.out.println(claims.getIssuedAt());
		System.out.println(claims.getIssuer());
	}
	
	/**
	 * 生成加密后的秘钥 secretKey
	 */
	public static SecretKey generalKey() {
		byte[] encodedKey = Base64.getDecoder().decode(JwtUtil.JWT_KEY);
		SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
		return key;
	}
	
	/**
	 * 解析
	 */
	public static Claims parseJWT(String jwt) throws Exception {
		SecretKey secretKey = generalKey();
		return Jwts.parser()
				.setSigningKey(secretKey)
				.parseClaimsJws(jwt)
				.getBody();
	}
}
